﻿using System;
using System.Linq;
using DDD.Domain;
using System.Linq.Expressions;
using System.Data.Entity;

namespace DDD.Infrastructure
{
    public class BaseRepository<T> : IBaseRepository<T> where T : class
    {
        protected DDDContext Context = new DDDContext();

        public T GetSingle(System.Linq.Expressions.Expression<Func<T, bool>> exp = null)
        {
            return Context.Set<T>().AsNoTracking().FirstOrDefault(exp);
        }

        public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> exp = null)
        {
            return Filter(exp);
        }

        public IQueryable<T> Find(int pageindex = 1, int pagesize = 10,Expression<Func<T, bool>> exp = null)
        {
            if (pageindex < 1) pageindex = 1;
            return Filter(exp).Skip(pagesize * (pageindex - 1)).Take(pagesize);
        }

        public int GetCount(System.Linq.Expressions.Expression<Func<T, bool>> exp = null)
        {
            throw new NotImplementedException();
        }

        public void Add(T entity)
        {
            Context.Set<T>().Add(entity);
            Save();
        }

        public void Update(T entity)
        {
            var entry = Context.Entry(entity);
            //todo:如果状态没有任何更改，会报错
            entry.State = EntityState.Modified;
            Save();
        }

        public void Delete(T entity)
        {
            var entry = Context.Entry(entity);
            entry.State = EntityState.Deleted;
            Save();
        }

        public void Update(Expression<Func<T, bool>> exp, T entity)
        {
            var entry = Context.Entry(entity);
            entry.State = EntityState.Deleted;
            Save();
        }

        public void Delete(Expression<Func<T, bool>> exp)
        {
            throw new NotImplementedException();
        }

        public void Save()
        {
            Context.SaveChanges();
        }
        private IQueryable<T> Filter(Expression<Func<T, bool>> exp)
        {
            var dbSet = Context.Set<T>().AsQueryable();
            if (exp != null)
                dbSet = dbSet.Where(exp);
            return dbSet;
        }
    }
}
